﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using hedefgrup.reports.renault.database;

namespace hedefgrup.reports.common
{
    public class Report_Dispersion : Report_Abstract
    {
        internal class Storage
        {
            SortedList<string, double> _Storage = new SortedList<string, double>();

            internal List<string> Dealers = new List<string>();

            internal void Increment(string dealerCode, string questionCode, string[] optionCodes, bool incrementDealerCount, bool incrementQuestionCount)
            {
                foreach (String optionCode in optionCodes)
                {
                    Increment(dealerCode, questionCode, optionCode, incrementDealerCount, incrementQuestionCount);
                    incrementQuestionCount = false;
                    incrementQuestionCount = false;
                }
            }

            internal double Get(string dealerCode, string questionCode, string optionCode)
            {
                if (!string.IsNullOrEmpty(dealerCode) && !string.IsNullOrEmpty(questionCode) && !string.IsNullOrEmpty(optionCode))
                {
                    if (_Storage.ContainsKey(dealerCode + questionCode + optionCode))
                    {
                        return _Storage[dealerCode + questionCode + optionCode];
                    }
                }
                return 0f;
            }

            internal double Get(string dealerCode, string questionCode)
            {
                if (!string.IsNullOrEmpty(dealerCode) && !string.IsNullOrEmpty(questionCode))
                {
                    if (_Storage.ContainsKey(dealerCode + questionCode))
                    {
                        return _Storage[dealerCode + questionCode];
                    }
                }
                return 0f;
            }

            internal double Get(string dealerCode)
            {
                if (!string.IsNullOrEmpty(dealerCode))
                {
                    if (_Storage.ContainsKey(dealerCode))
                    {
                        return _Storage[dealerCode];
                    }
                }
                return 0f;
            }

            internal void Increment(string dealerCode, string questionCode, string optionCode, bool incrementDealerCount, bool incrementQuestionCount)
            {
                if (!string.IsNullOrEmpty(dealerCode) && !string.IsNullOrEmpty(questionCode) && !string.IsNullOrEmpty(optionCode))
                {
                    dealerCode = dealerCode.Trim();

                    if (!Dealers.Contains(dealerCode))
                    {
                        Dealers.Add(dealerCode);
                    }

                    if (_Storage.ContainsKey(dealerCode + questionCode + optionCode))
                    {
                        _Storage[dealerCode + questionCode + optionCode]++;
                        if (incrementDealerCount)
                        {
                            _Storage[dealerCode]++;
                        }
                        if (incrementQuestionCount)
                        {
                            _Storage[dealerCode + questionCode]++;
                        }
                    }
                    else
                    {
                        _Storage.Add(dealerCode + questionCode + optionCode, 1f);

                        if (incrementDealerCount)
                        {
                            if (_Storage.ContainsKey(dealerCode))
                            {
                                _Storage[dealerCode]++;
                            }
                            else
                            {
                                _Storage.Add(dealerCode, 1f);
                            }
                        }

                        if (incrementQuestionCount)
                        {
                            if (_Storage.ContainsKey(dealerCode + questionCode))
                            {
                                _Storage[dealerCode + questionCode]++;
                            }
                            else
                            {
                                _Storage.Add(dealerCode + questionCode, 1f);
                            }
                        }

                    }
                }
            }
        }

        private void ProcessRow(DataRow reportRow, Storage storage)
        {
            string s18 = reportRow["S18"].ToString();
            string s17 = reportRow["S17"].ToString();
            string[] s17a = reportRow["s17a"].ToString().Trim().Split(',');
            string dealerCode = reportRow[base.DealerColumn].ToString();

            storage.Increment("_TOTAL", "S18", s18, true, true);
            storage.Increment("_TOTAL", "S17", s17, false, true);
            storage.Increment("_TOTAL", "S17a", s17a, false, true);

            storage.Increment(dealerCode, "S18", s18, true, true);
            storage.Increment(dealerCode, "S17", s17, false, true);
            storage.Increment(dealerCode, "S17a", s17a, false, true);
        }

        public override ReportResult GenerateReport()
        {
            ReportResult results = new ReportResult(this);

            DataTable reportData = db.query
            (
                "SELECT " + base.DealerColumn + ", KOORDINATOR, " + AreaColumn + ", S18, S17, S17a FROM " + Context.TableName + " " +
                GetSqlStatementFilter(),
                base.GetSqlStatementParameters()
            );

            Storage storage = new Storage();

            foreach (DataRow reportRow in reportData.Rows)
            {
                ProcessRow(reportRow, storage);
            }

            Row headerRow = new Row();
            results.HeaderRows.Add(headerRow);

            headerRow.Cells.Add(new Cell() { Text = "Bayii Kodu" });

            headerRow.Cells.Add(new Cell() { Text = "Bayii Adı" });

            headerRow.Cells.Add(new Cell() { Text = "Baz" });

            Tree s18Tree = Context.Questionnaire.Select("S18")[0];
            headerRow.Cells.Add(new Cell() { Text = s18Tree.Text });

            Tree s17aTree = Context.Questionnaire.Select("S17a")[0];
            foreach (Tree s17aOption in s17aTree.Children)
            {
                headerRow.Cells.Add(new Cell() { Text = s17aOption.Text });
            }

            headerRow.Cells.Add(new Cell() { Text = Context.Questionnaire.Select("S17")[0].Text });

            storage.Dealers.Sort();

            foreach (string dealerCode in storage.Dealers)
            {
                Row reportRow = new Row();
                results.Rows.Add(reportRow);

                if (dealerCode == "_TOTAL")
                {
                    reportRow.Cells.Add(new Cell() { });
                    reportRow.Cells.Add(new Cell() { Text = "Genel", TextAlign = "left" });
                }
                else
                {
                    reportRow.Cells.Add(new DealerCodeCell() { Text = dealerCode });
                    reportRow.Cells.Add(new Cell() { Text = GetDealerName(dealerCode), TextAlign = "left" });
                }

                reportRow.Cells.Add(new Cell() { Text = storage.Get(dealerCode).ToString() });

                double s18Count = storage.Get(dealerCode, "S18");
                double value = storage.Get(dealerCode, "S18", "1");
                reportRow.Cells.Add(new Cell() { Text = string.Format("{0:0.0000000000000}", s18Count > 0 ? 100 * (value / s18Count) : 0d) });

                double countOfDealer = storage.Get(dealerCode);
                foreach (Tree s17aoption in s17aTree.Children)
                {
                    double value2 = storage.Get(dealerCode, "S17a", s17aoption.Key);
                    reportRow.Cells.Add(new Cell() { Text = string.Format("{0:0.0000000000000}", value2 > 0 ? 100 * (value2 / countOfDealer) : 0d) });
                }

                double s17 = storage.Get(dealerCode, "S17", "1");
                double s17Value = 100 * (s17 / storage.Get(dealerCode));
                reportRow.Cells.Add(new Cell() { Text = string.Format("{0:0.0000000000000}", s17Value) });
            }

            return results;
        }

        public override string DisplayName
        {
            get { return "Dispersion"; }
        }

        protected override void SetCriteriaList()
        {
            Criterias.Add(new Criteria_Roll() { Context = Context });
            Criterias.Add(new Criteria_EndMonth() { Context = Context });
            Criterias.Add(new Criteria_Network() { Context = Context });
            Criterias.Add(new Criteria_Organization() { Context = Context });
        }

        public override string SortPrefix
        {
            get { return "0x01"; }
        }

        public override bool Authorized
        {
            get
            {
                return base.GetAuthLevel() != "dealer";
            }
        }
    }
}
